<script src="/js/functions.js"></script>
<script src="/js/utils.js"></script>
<script src="/js/dump.js"></script>
<script src="lex.js"></script>
<script>

var trace = function(x) {
	document.write('<pre>' + sprintf.apply(this, arguments) + '</pre>');
};



var Stream = function(str) {
	this.load(str);
};
Stream.prototype = {
	EOF: -1,
	load: function(str) {
		this.source = str;
		this.length = this.source.length;
		this.reset();
	},
	eof: function() {
		return this.char === this.EOF;
	},
	reset: function() {
		this.pos = 0;
	},
	getch: function() {
		if (this.pos >= this.length)
			return this.char = this.EOF;
		return this.char = this.source[this.pos++];
	}
};


var parse_re = function(source) {
	var rec = function(stream, result) {
		var c = stream.getch();
		switch (c) {
			case stream.EOF:
				return result;
			case '|':
				var x = rec(stream, []);
				return ['|', result, x];
			case '(':
				var x = rec(stream, []);
				result.push(x);
				return rec(stream, result);
			case ')':
				return result.length == 1 ? result[0] : result;
			case '?':
				result.push(['?', result.pop()]);
				return rec(stream, result);
			default:
				result.push([['C', c]]);
				return rec(stream, result);
		}
	};
	var stream = new Stream(source);
	var result = rec(stream, []);
	result.source = source;
	return result;
};


var lex_re = function(re) {
	var rec = function(re, next) {
		var last = {};
		var first = last;
		var n;
		for (var i = 0, max = re.length; i < max; ++i) {
			n = i == max - 1 ? next : {};
			switch (re[i][0]) {
				case 'C':
					var x = {};
					x[re[i][1]] = n;
					lex_merge(last, x);
					last = n;
					break;
				case '|':
					var xx = rec(re[i][1], n);
					//alert(jsonrpc_json_encode(xx));
					var yy = re[i][2].length ? rec(re[i][2], n) : [n];
					lex_merge(xx[0], yy[0]);
					for (var j in xx[0])
						last[j] = xx[0][j];
					last = n;
					break;
				case '?':
					var xx = rec(re[i][1], n);
					lex_merge(xx[0], n);
					lex_merge(last, xx[0]);
					last = n;
					break;
				default:
					//alert(jsonrpc_json_encode(n));
					var xx = rec(re[i], n);
					//for (var j in xx[0])
					//	last[j] = xx[0][j];
					lex_merge(last, xx[0]);
					last = n;
			}
		}
		return [first, last];
	};
	next = { action: "RE: " + (re.source || re)};
	re = [re];
	trace(jsonrpc_json_encode(re));
	var xx = rec(re, next);
	return xx;
};


var x, b;
x = { start: 0 };
b0 = {};
x.a = b0;
x.any = x;
b = {};
b0.b = b;
b.b = b;
b.c = { finish: 0 };

//lex_merge(x

//alert(dump(x));


lex_run2(x, 'aabc');




/*
var re = parse_re('ab?c');
//re = [[["C", "a"]], ["C", "b"]];
var xx = lex_re(re);
var x = xx[0];
console.dir(x);
trace(jsonrpc_json_encode(x));
*/



</script>















